package com.xuyuan.thread.threadcorporation;

import com.xuyuan.util.ConsoleColors;

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionCorporationExample {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ServiceExample2 example = new ServiceExample2();
        executorService.execute(example::awaitMethod);
        executorService.execute(example::awaitMethod);
        executorService.execute(example::awaitMethod);
        executorService.execute(example::awaitMethod);
        executorService.execute(example::awaitMethod);
        Thread.sleep(5000);
        executorService.execute(example::signalAllMethod);
    }
}

class ServiceExample2 {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void signalAllMethod() {
        lock.lock();
        try {
            System.out.println(ConsoleColors.GREEN + Thread.currentThread().getName() + " signalAll begin:" + LocalDateTime.now() + ConsoleColors.RESET);
            condition.signalAll();
            System.out.println(ConsoleColors.GREEN + Thread.currentThread().getName() + " signalAll success:" + LocalDateTime.now() + ConsoleColors.RESET);
            System.out.println(ConsoleColors.GREEN + Thread.currentThread().getName() + " 正在执行当前逻辑" + LocalDateTime.now() + ConsoleColors.RESET);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(ConsoleColors.GREEN + Thread.currentThread().getName() + " 执行完成释放锁资源" + LocalDateTime.now() + ConsoleColors.RESET);
        } finally {
            lock.unlock();
        }
    }

    public void awaitMethod() {
        lock.lock();
        try {
            System.out.println(ConsoleColors.RED + Thread.currentThread().getName() + "await begin:" + LocalDateTime.now() + ConsoleColors.RESET);
            condition.await();
            System.out.println(ConsoleColors.RED + Thread.currentThread().getName() + "await end:" + LocalDateTime.now() + ConsoleColors.RESET);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
